Skip to content

feat(notifications): add ntfy markdown formatting#2602

Open
v3DJG6GL wants to merge 9 commits intoseerr-team:developfrom
v3DJG6GL:ntfy-markdown
Open

feat(notifications): add ntfy markdown formatting#2602
v3DJG6GL wants to merge 9 commits intoseerr-team:developfrom
v3DJG6GL:ntfy-markdown

Conversation

@v3DJG6GL
Copy link

@v3DJG6GL v3DJG6GL commented Feb 28, 2026

Description

This PR adds markdown formatting ntfy notifications. Both server & android app support markdown formating

AI Disclosure: Claude Sonnet helped me finding relevant code & files. The final implementation and code checks however were done manually by me.

  • Fixes #XXXX

How Has This Been Tested?

I've been running these for about two months without any issues on two instances.

Movie Request Approved

Screenshot 2025-12-22 at 20-01-20 (121) ntfy

Movie Request Available

Screenshot 2025-12-22 at 20-01-30 (121) ntfy

New Video Issue Reported

Screenshot 2025-12-22 at 20-03-32 (121) ntfy

New Comment on Video Issue

Screenshot 2025-12-22 at 20-04-46 (121) ntfy

Issue resolved

Screenshot 2025-12-22 at 20-05-49 (121) ntfy

Checklist:

  • I have read and followed the contribution guidelines.
  • Disclosed any use of AI (see our policy)
  • I have updated the documentation accordingly.
  • All new and existing tests passed.
  • Successful build pnpm build
  • Translation keys pnpm i18n:extract
  • Database migration (if required)

Summary by CodeRabbit

  • New Features
    • Notifications now use Markdown with bold, labeled sections (Description, Request Status, Comment, Comment from, Reported By, Issue Type, Issue Status) for clearer, structured messages.
    • Request, comment, and issue messages prepend a Description/Comment header when present and always include requester/commenter/creator names with Markdown-escaped text for safe, consistent display.
    • Payloads are delivered as Markdown-enabled messages for richer, formatted notifications.

@v3DJG6GL v3DJG6GL requested a review from a team as a code owner February 28, 2026 10:51
@coderabbitai
Copy link

coderabbitai bot commented Feb 28, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Ntfy notification agent: added a Markdown-escaping helper, restructured message composition to use bold headers for request/comment/issue payloads, and ensures the returned payload includes markdown: true.

Changes

Cohort / File(s) Summary
Notification Formatting & Escaping
server/lib/notifications/agents/ntfy.ts
Added private escapeMarkdown(text: string). Reworked buildPayload to prepend bold headers (e.g., - Description, - Requested By, - Comment, - Comment from, - Reported By, - Issue Type, - Issue Status), escape requester/commenter/creator names, adjust request/comment/issue message composition, and always set markdown: true on the returned payload.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 I nibbled through each star and dash,
Escaped the markdown in a flash,
Bold headings placed in tidy rows,
I hopped through names and fixed the flows,
A joyful bounce — the payload glows ✨

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding markdown formatting support to ntfy notifications, which aligns with the substantial code modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
server/lib/notifications/agents/ntfy.ts (1)

38-41: Avoid leading blank lines when request message starts empty.

On Line 41 and Line 64, unconditional newline prefixes can produce a notification body that starts with empty lines.

💡 Minimal diff
-      message += `\n\n**- Requested By:** ${payload.request.requestedBy.displayName}`;
+      message += `${message ? '\n\n' : ''}**- Requested By:** ${payload.request.requestedBy.displayName}`;-        message += `\n**- Request Status:** ${status}`;
+        message += `${message ? '\n' : ''}**- Request Status:** ${status}`;

Also applies to: 64-64

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/lib/notifications/agents/ntfy.ts` around lines 38 - 41, The
message-building logic in ntfy.ts currently prepends or appends sections with
unconditional "\n\n" which can produce leading blank lines when the initial
message is empty; update the code that mutates the variable message (the block
that sets message = `**- Description:**\n${message}` and the later append that
adds `\n\n**- Requested By:** ${payload.request.requestedBy.displayName}`) to
conditionally add the preceding newlines only when message is non-empty,
otherwise set the section text without leading blank lines so the final
notification body never starts with empty lines.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@server/lib/notifications/agents/ntfy.ts`:
- Around line 67-75: The message construction uses unescaped user-provided
metadata (payload.comment.user.displayName, payload.issue.createdBy.displayName
and similar) while ntfy is sent with markdown: true; implement and call a
sanitizing helper (e.g., escapeMarkdown) to escape markdown metacharacters for
all interpolated metadata fields before concatenation into message, but do NOT
escape the actual comment body (payload.comment.message) so its markdown remains
intact; update the places where message is built (references: message variable
assignment, payload.comment.user.displayName,
payload.issue.createdBy.displayName, IssueTypeName interpolation) to use the
sanitizer.

---

Nitpick comments:
In `@server/lib/notifications/agents/ntfy.ts`:
- Around line 38-41: The message-building logic in ntfy.ts currently prepends or
appends sections with unconditional "\n\n" which can produce leading blank lines
when the initial message is empty; update the code that mutates the variable
message (the block that sets message = `**- Description:**\n${message}` and the
later append that adds `\n\n**- Requested By:**
${payload.request.requestedBy.displayName}`) to conditionally add the preceding
newlines only when message is non-empty, otherwise set the section text without
leading blank lines so the final notification body never starts with empty
lines.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f74306e and 02f16c0.

📒 Files selected for processing (1)
  • server/lib/notifications/agents/ntfy.ts

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Markdown-formatted message bodies for the ntfy notification agent so notifications render with labeled sections (description/request status/comment/issue metadata) in clients that support Markdown.

Changes:

  • Reformats ntfy notification message content to include Markdown emphasis and labeled sections.
  • Enables Markdown rendering in ntfy payloads via markdown: true.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
server/lib/notifications/agents/ntfy.ts (1)

41-45: Consider extracting a tiny section-builder helper for repeated string assembly.

The same “prepend/append labeled block with conditional spacing” pattern appears in multiple branches; a helper would reduce drift in future edits.

Also applies to: 71-75, 77-83

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/lib/notifications/agents/ntfy.ts` around lines 41 - 45, Extract the
repeated "prepend/append labeled block with conditional spacing" logic into a
small helper (e.g., appendLabeledBlock(existingMessage, label, content)) inside
ntfy.ts and use it wherever that pattern appears: replace the payload.request
branch that manipulates message, the similar block around lines 71-75, and the
block at 77-83; the helper should take the current message string, a label like
"Description" or "Requested By", and the escaped content (use
this.escapeMarkdown(payload.request.requestedBy.displayName) when appropriate),
and return the new message string with correct spacing and formatting so callers
(the code touching message and payload.request) just call the helper instead of
manually concatenating.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@server/lib/notifications/agents/ntfy.ts`:
- Around line 41-45: Extract the repeated "prepend/append labeled block with
conditional spacing" logic into a small helper (e.g.,
appendLabeledBlock(existingMessage, label, content)) inside ntfy.ts and use it
wherever that pattern appears: replace the payload.request branch that
manipulates message, the similar block around lines 71-75, and the block at
77-83; the helper should take the current message string, a label like
"Description" or "Requested By", and the escaped content (use
this.escapeMarkdown(payload.request.requestedBy.displayName) when appropriate),
and return the new message string with correct spacing and formatting so callers
(the code touching message and payload.request) just call the helper instead of
manually concatenating.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 02f16c0 and 8ee7789.

📒 Files selected for processing (1)
  • server/lib/notifications/agents/ntfy.ts

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@v3DJG6GL v3DJG6GL requested a review from gauthier-th March 2, 2026 21:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants